#include <iostream>
#include <numeric>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <memory>
#include <sstream>
#include <set>
#include <unordered_map>
#include <iomanip>
#include <cstring>
#include <stdlib.h>
#include <thread>
#include <mutex>
#include <fstream>

using namespace std;

class Tensor {
public:
    Tensor(vector<int> shape) {
        int data_size = std::accumulate(shape.begin(), shape.end(), 0);
        data_ = vector<int>(data_size, 0);
        shape_ = shape;
    }

    void shape() {
        for (auto i = 0; i < shape_.size(); i++) {
            if (i == 0) cout << "<";
            cout << shape_[i];
            if (i != shape_.size()-1) cout << ",";
            if (i == shape_.size()-1) cout << ">" << endl;
        }
    }

    void print() {
        if (shape_.size() == 1) {
            for (auto i : shape_) cout << data_[i] << " ";
            cout << endl;
        }
        if (shape_.size() == 2) {
            for (int i = 0; i < shape_[0]; i++) {
                for (int j = 0; j < shape_[1]; j++) {
                    cout << data_[i * shape_[1] + j] << " ";
                }
                cout << endl;
            }
        }
    }

    Tensor &operator[](int index) {
        index_.push_back(index);
        return *this;
    }

    void operator=(const int &value) {
        int offset = std::accumulate(index_.begin(), index_.end(), 0);
        if (offset > data_.size()) {
            cout << "index is out of bound" << endl;
            throw;
        }
        data_[offset] = value;
    }

    operator int() const {
        int offset = std::accumulate(index_.begin(), index_.end(), 0);
        if (offset > data_.size()) {
            cout << "index is out of bound" << endl;
            throw;
        }
        return data_[offset];
    }
private:
    vector<int> index_{};
    vector<int> data_{};
    vector<int> shape_{};
};

int main() {
    Tensor obj({2,3});
    obj.shape();
    obj.print();
    obj[0][0] = 1;
    obj.print();
    int val = obj[0][0];
    cout << val << endl;
    cout << obj[0][0] + obj[0][0] << endl;
    obj[0][0] = obj[0][0] + obj[0][0];
    obj.print();
    obj[0] = obj[0] + obj[0];
    obj.print();
    cout << (obj[0][0] > 1) << endl;
    return 0;
}
